package com.ai.imagetext.service;

import com.ai.imagetext.dto.AIRecognitionResult;
import com.ai.imagetext.entity.Image;
import com.ai.imagetext.entity.ImageTag;
import com.ai.imagetext.entity.Tag;
import com.ai.imagetext.repository.ImageRepository;
import com.ai.imagetext.repository.ImageTagRepository;
import com.ai.imagetext.repository.TagRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AIRecognitionService {
    
    private final AIService aiService;
    private final ImageRepository imageRepository;
    private final TagRepository tagRepository;
    private final ImageTagRepository imageTagRepository;
    private final ObjectMapper objectMapper = new ObjectMapper();


    /**
     * 异步识别图片并更新数据库
     */
    @Async
    @Transactional
    public void recognizeImageTag(Image image,Long userId) {
        Long imageId = image.getId();
        log.info("Starting AI recognition for image: {}", imageId);

        try {
            // 更新状态为处理中
            image.setAiRecognitionStatus(Image.AIRecognitionStatus.PENDING);
            imageRepository.save(image);

            // 调用AI识别服务
            Map<String, Object> responseMap = aiService.imageToTage(image);
            Map<String, Object> bodyMap = (Map<String, Object>) responseMap.get("body");
            Map<String, Object> dataMap = (Map<String, Object>) bodyMap.get("Data");
            StringBuilder stringBuilder = new StringBuilder();
            ArrayList list=(ArrayList)dataMap.get("Tags");
            for(Object o:list){
                HashMap o1 = (HashMap) o;
                stringBuilder.append(o1.get("Value"));
                stringBuilder.append(",");
            }
            String substring = stringBuilder.substring(0, stringBuilder.length() - 1);
            image.setTags(substring);
            dataMap.values().forEach(value -> {
                ArrayList<HashMap<String, Object>> temp = (ArrayList<HashMap<String, Object>>) value;
                for (HashMap<String, Object> d : temp) {
                    String name = (String) d.get("Value");
                    Tag tag = new Tag();
                    tag.setName(name);

                    tag.setUserId(userId);

                    if(tagRepository.findOrCreateByName(name).isEmpty()) {
                        tagRepository.save(tag);
                    }
                    Float confidence = (Float) d.get("Confidence");
                    tag = tagRepository.findByNameAndIsDeletedFalse(name).get();
                    ImageTag imageTag = new ImageTag();

                    imageTag.setTag(tag);
                    imageTag.setImage(image);
                    imageTag.setConfidence(new BigDecimal(confidence.toString()).setScale(2, RoundingMode.HALF_UP));
                    imageTagRepository.save(imageTag);
                }
            });
            // 更新状态为完成
            image.setAiRecognitionStatus(Image.AIRecognitionStatus.SUCCESS);
            imageRepository.save(image);

        } catch (Exception e) {
            log.error("Unexpected error during AI recognition for image: {}", imageId, e);
            processFailedRecognition(image, "系统错误: " + e.getMessage());
        }
    }

    /**
     * 异步识别图片并更新数据库
     */
    @Async
    @Transactional
    public void recognizeAndUpdateImage(Image image) {
        log.info("Starting AI recognition for image: {}", image.getId());
        
        try {
            // 更新状态为处理中
            image.setAiRecognitionStatus(Image.AIRecognitionStatus.PENDING);
            imageRepository.save(image);
            
            // 调用AI识别服务
            AIRecognitionResult result = aiService.recognizeImage(image.getFileUrl());
            
            if (result.isSuccess()) {
                // 处理识别成功的结果
                processSuccessfulRecognition(image, result);
                log.info("AI recognition completed successfully for image: {}", image.getId());
            } else {
                // 处理识别失败的情况
                processFailedRecognition(image, result.getErrorMessage());
                log.warn("AI recognition failed for image: {}, error: {}", image.getId(), result.getErrorMessage());
            }
            
        } catch (Exception e) {
            log.error("Unexpected error during AI recognition for image: {}", image.getId(), e);
            processFailedRecognition(image, "系统错误: " + e.getMessage());
        }
    }
    
    /**
     * 处理识别成功的结果
     */
    private void processSuccessfulRecognition(Image image, AIRecognitionResult result) {
        try {
            // 更新图片信息
            image.setAiRecognitionStatus(Image.AIRecognitionStatus.SUCCESS);
            image.setDescription(result.getDescription());
            
            // 保存AI识别结果
            String recognitionResultJson = objectMapper.writeValueAsString(result);
            image.setAiRecognitionResult(recognitionResultJson);
            
            // 处理标签
            List<String> tagNames = processAndSaveTags(image, result.getTags());
            
            // 更新图片的tags字段
            image.setTags(String.join(",", tagNames));
            
            // 保存图片更新
            imageRepository.save(image);
            
        } catch (Exception e) {
            log.error("Error processing successful recognition for image: {}", image.getId(), e);
            processFailedRecognition(image, "处理识别结果时出错: " + e.getMessage());
        }
    }
    
    /**
     * 处理识别失败的情况
     */
    private void processFailedRecognition(Image image, String errorMessage) {
        try {
            image.setAiRecognitionStatus(Image.AIRecognitionStatus.FAILED);
            image.setAiRecognitionResult("{\"error\": \"" + errorMessage + "\"}");
            imageRepository.save(image);
        } catch (Exception e) {
            log.error("Error updating failed recognition status for image: {}", image.getId(), e);
        }
    }
    
    /**
     * 处理并保存标签
     */
    private List<String> processAndSaveTags(Image image, List<AIRecognitionResult.TagInfo> aiTags) {
        List<String> tagNames = new ArrayList<>();
        
        if (aiTags == null || aiTags.isEmpty()) {
            return tagNames;
        }
        
        // 删除现有的AI生成的标签关联
        List<ImageTag> existingAITags = imageTagRepository.findByImageIdAndSource(
                image.getId(), ImageTag.TagSource.AI);
        imageTagRepository.deleteAll(existingAITags);
        
        // 处理新标签
        for (AIRecognitionResult.TagInfo aiTag : aiTags) {
            try {
                // 查找或创建标签
                Tag tag = findOrCreateTag(aiTag);
                
                // 创建图片标签关联
                ImageTag imageTag = new ImageTag();
                imageTag.setImage(image);
                imageTag.setTag(tag);
                imageTag.setConfidence(BigDecimal.valueOf(aiTag.getConfidence()));
                imageTag.setSource(ImageTag.TagSource.AI);
                
                imageTagRepository.save(imageTag);
                tagNames.add(tag.getName());
                
                log.debug("Added AI tag '{}' to image {} with confidence {}", 
                         tag.getName(), image.getId(), aiTag.getConfidence());
                
            } catch (Exception e) {
                log.warn("Failed to process AI tag '{}' for image {}: {}", 
                        aiTag.getName(), image.getId(), e.getMessage());
            }
        }
        
        return tagNames;
    }
    
    /**
     * 查找或创建标签
     */
    private Tag findOrCreateTag(AIRecognitionResult.TagInfo aiTag) {
        Optional<Tag> existingTag = tagRepository.findByNameAndIsDeletedFalse(aiTag.getName());
        
        if (existingTag.isPresent()) {
            return existingTag.get();
        }
        
        // 创建新标签
        Tag newTag = new Tag();
        newTag.setName(aiTag.getName());
        newTag.setCategory(aiTag.getCategory() != null ? aiTag.getCategory() : "ai_generated");
        newTag.setUsageCount(0);
        newTag.setIsDeleted(false);
        
        return tagRepository.save(newTag);
    }
    
    /**
     * 手动触发图片识别
     */
    @Transactional
    public AIRecognitionResult manualRecognizeImage(Long imageId) {
        log.info("Manual recognition triggered for image: {}", imageId);
        
        Image image = imageRepository.findByIdAndIsDeletedFalse(imageId)
                .orElseThrow(() -> new IllegalArgumentException("图片不存在或已删除"));
        
        // 调用AI识别服务
        AIRecognitionResult result = aiService.recognizeImage(image.getFileUrl());
        
        if (result.isSuccess()) {
            // 同步处理识别结果
            processSuccessfulRecognition(image, result);
        } else {
            processFailedRecognition(image, result.getErrorMessage());
        }
        
        return result;
    }
    
    /**
     * 批量识别图片
     */
    @Async
    @Transactional
    public void batchRecognizeImages(List<Long> imageIds) {
        log.info("Starting batch recognition for {} images", imageIds.size());
        
        List<Image> images = imageRepository.findAllById(imageIds)
                .stream()
                .filter(image -> !image.getIsDeleted())
                .collect(Collectors.toList());
        
        for (Image image : images) {
            try {
                recognizeAndUpdateImage(image);
                
                // 添加延迟以避免API频率限制
                Thread.sleep(1000);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("Batch recognition interrupted");
                break;
            } catch (Exception e) {
                log.error("Error in batch recognition for image: {}", image.getId(), e);
            }
        }
        
        log.info("Batch recognition completed for {} images", images.size());
    }
    
    /**
     * 重新识别失败的图片
     */
    @Async
    @Transactional
    public void retryFailedRecognitions() {
        log.info("Retrying failed AI recognitions");
        
        List<Image> failedImages = imageRepository.findByAiRecognitionStatusAndIsDeletedFalse(
                Image.AIRecognitionStatus.FAILED);
        
        log.info("Found {} failed recognition images to retry", failedImages.size());
        
        for (Image image : failedImages) {
            try {
                recognizeAndUpdateImage(image);
                
                // 添加延迟以避免API频率限制
                Thread.sleep(2000);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("Retry failed recognitions interrupted");
                break;
            } catch (Exception e) {
                log.error("Error retrying recognition for image: {}", image.getId(), e);
            }
        }
        
        log.info("Retry failed recognitions completed");
    }
    
    /**
     * 获取识别统计信息
     */
    public RecognitionStatistics getRecognitionStatistics() {
        long totalImages = imageRepository.countByIsDeletedFalse();
        long successCount = imageRepository.countByAiRecognitionStatusAndIsDeletedFalse(
                Image.AIRecognitionStatus.SUCCESS);
        long failedCount = imageRepository.countByAiRecognitionStatusAndIsDeletedFalse(
                Image.AIRecognitionStatus.FAILED);
        long pendingCount = imageRepository.countByAiRecognitionStatusAndIsDeletedFalse(
                Image.AIRecognitionStatus.PENDING);
        
        RecognitionStatistics stats = new RecognitionStatistics();
        stats.setTotalImages(totalImages);
        stats.setSuccessCount(successCount);
        stats.setFailedCount(failedCount);
        stats.setPendingCount(pendingCount);
        stats.setSuccessRate(totalImages > 0 ? (double) successCount / totalImages * 100 : 0.0);
        
        return stats;
    }
    
    /**
     * 识别统计信息
     */
    public static class RecognitionStatistics {
        private long totalImages;
        private long successCount;
        private long failedCount;
        private long pendingCount;
        private double successRate;
        
        // Getters and Setters
        public long getTotalImages() { return totalImages; }
        public void setTotalImages(long totalImages) { this.totalImages = totalImages; }
        
        public long getSuccessCount() { return successCount; }
        public void setSuccessCount(long successCount) { this.successCount = successCount; }
        
        public long getFailedCount() { return failedCount; }
        public void setFailedCount(long failedCount) { this.failedCount = failedCount; }
        
        public long getPendingCount() { return pendingCount; }
        public void setPendingCount(long pendingCount) { this.pendingCount = pendingCount; }
        
        public double getSuccessRate() { return successRate; }
        public void setSuccessRate(double successRate) { this.successRate = successRate; }
    }
}